#pragma once

#include <map>
#include <vector>

#include "WallpaperEngine/Audio/AudioStream.h"
#include "WallpaperEngine/Audio/Drivers/AudioDriver.h"

#include <SDL.h>

#define MAX_AUDIO_FRAME_SIZE 192000

namespace WallpaperEngine::Audio::Drivers {
/**
 * Audio output buffers for streams being played under SDL
 */
struct SDLAudioBuffer {
    AudioStream* stream = nullptr;
    uint8_t audio_buf [(MAX_AUDIO_FRAME_SIZE * 3) / 2] = {0};
    unsigned int audio_buf_size = 0;
    unsigned int audio_buf_index = 0;
};

/**
 * SDL's audio driver implementation
 */
class SDLAudioDriver final : public AudioDriver {
  public:
    SDLAudioDriver (
        Application::ApplicationContext& applicationContext, Detectors::AudioPlayingDetector& detector,
        Recorders::PlaybackRecorder& recorder);
    ~SDLAudioDriver () override;

    /** @inheritdoc */
    void addStream (AudioStream* stream) override;
    /**
     * @return All the registered audio streams
     */
    const std::vector<SDLAudioBuffer*>& getStreams ();

    /** @inheritdoc */
    [[nodiscard]] AVSampleFormat getFormat () const override;
    /** @inheritdoc */
    [[nodiscard]] int getSampleRate () const override;
    /** @inheritdoc */
    [[nodiscard]] int getChannels () const override;
    /**
     * @return The SDL's audio driver settings
     */
    [[nodiscard]] const SDL_AudioSpec& getSpec () const;

  private:
    /** The device's ID */
    SDL_AudioDeviceID m_deviceID;
    /** If the driver is initialized or not */
    bool m_initialized = false;
    /** The sound output configuration */
    SDL_AudioSpec m_audioSpec {};
    /** All the playable steams */
    std::vector<SDLAudioBuffer*> m_streams {};
};
} // namespace WallpaperEngine::Audio::Drivers